using System.Text;
using System.Xml;
using SharpObjects.Configuration;
using SharpObjects.Configuration.ConfigurationProviders;
using SharpObjects.Logging.Utils;

namespace SharpObjects.Logging.Formatters
{
	public class DefaultLogFormatter : LogFormatterBase
	{
		public abstract class Tags : LogFormatterBase.Tags
		{
			public const string timeFormat = "time_format";
		}

	    protected const string indent = "    ";
		protected string timeFormat = "G";


		public DefaultLogFormatter()
		{
			this.ValueDelimiter = "\r\n";
		}

		//#region ILogFormatter Members

		public override string ApplyFormat(ILogEntry logEntry)
		{
			StringBuilder sb = new StringBuilder();

			sb.Append(this.ValueDelimiter);
			sb.Append(this.MessageSeparator);
			sb.Append(this.ValueDelimiter);
			sb.Append(logEntry.Time.ToString(this.timeFormat));
		    sb.Append(indent);
			sb.Append("Machine: ");
			sb.Append(logEntry.MachineName);

			if(ProcessInformation.UseProcessInfo)
			{
				sb.Append(this.ValueDelimiter);
                sb.Append(indent);
                sb.Append("Process: ");
				sb.Append(logEntry.ProcessName);
				sb.Append(" (");
				sb.Append(logEntry.ProcessId.ToString());
				sb.Append(")");
			}

			sb.Append(", ");
			sb.Append(logEntry.ThreadTag);
			sb.Append(this.ValueDelimiter);
            sb.Append(indent);
            sb.Append("Category: ");
			sb.Append(logEntry.Category);
            sb.Append(indent);
			sb.Append("Origin: ");
			sb.Append(logEntry.Origin);
			
			sb.Append(this.ValueDelimiter);

			sb.Append(logEntry.Message);

			if(!string.IsNullOrEmpty(logEntry.StackTrace))
			{
				sb.Append(this.ValueDelimiter);
                sb.Append(indent);
                sb.Append("Stack Trace:\r\n");
				sb.Append(logEntry.StackTrace);
			}

			sb.Append(this.ValueDelimiter);

			return sb.ToString();
		}



		//#endregion
		
		public override void Initialize(XmlElement initializationElement)
		{
			base.Initialize (initializationElement);

			IConfigurationProvider config = new XmlConfigurationProvider(initializationElement);
			this.timeFormat = config.GetString(Tags.timeFormat, this.timeFormat);

		}

	}
}
